/* ----------------------------------------------------------------------------------------------------------------
 * AnimationRenderer
 * ----------------------------------------------------------------------------------------------------------------
 */
package pure.engine.renderer 
{
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import pure.utils.DesN;
	import pure.engine.renderer.sections.Action;
	import pure.engine.renderer.sections.Section;
	import pure.engine.renderer.sections.SectionManager;
	import pure.engine.system.ns_despair;
		
	use namespace ns_despair;
	
	/**
	 * 动画渲染器
	 * 
	 * @author Pure
	 */
public class AnimationRenderer extends Renderer implements IAnimation
{
	public function AnimationRenderer()
	{
		m_visible = false;
	}
	

	
	private var m_onComplete:Object = { };
	
	private var m_onCompleteParams:Object = { };

	
	
	protected var _section:Section;
	
	protected var _playing:Boolean;
	
	protected var _currGroup:Vector.<uint>;
	
	protected var _pointer:int, _currIndex:int, _groupLen:int, cachedTime:int, cachedDelay:int;
	
	protected var _playScale:Number = 1.0;
	
	protected var _actionOrPointer:*;


	public function setSection(sectionName:String):void 
	{
		if (this.section == sectionName)  return;
		
		if (sectionName == null || sectionName == '')
		{
			m_visible  =  false;
			_section  =  null;
		}
		
		else
		{
			_section      =  SectionManager.getSection(sectionName);
			m_x            =  _section.m_x;
			m_y            =  _section.m_y;
			m_realRect     =  _section.m_realRect.clone();
			m_range        =  _section.m_range;
			_pointer      =  1;
			_playing      =  false;
			m_visible      =  true;
			//trace('[ProcessManager] - Section更换:' + sectionName);
		}
		
		m_rangeDirty   =  true;
		m_bufferDirty  =  true;
	}
	
	
	public function play(actionOrPointer:*, onComplete:Function = null , ...rest ):void
	{
		if(int(actionOrPointer))
		{
			_advancePointer(_actionOrPointer = actionOrPointer);
			_playing = false;
		}
		
		else if(actionOrPointer is String)
		{
			var action:Action;
			
			if (_playing && _actionOrPointer == actionOrPointer) return;
			
			_actionOrPointer = actionOrPointer;
			action = _section.getActionByName(_actionOrPointer)
			if (!action) 
			{
				throw new Error("片段（ "+_section.m_name+" ） - ＃play - 不存在的动作（ "+_actionOrPointer+" ）");
			}
			
			_currGroup    =  action.group;
			_groupLen     =  _currGroup.length;
			_currIndex    =  0;
			_pointer      =  _currGroup[_currIndex];
			m_bufferDirty  =  true;
			
			if (this._groupLen <= 1) 
			{
				_playing = false;
				return;
			}
			
			_playing                       =  true;
			m_onComplete.animation  =  onComplete;
			cachedDelay                 =  (action.delay / _playScale) >> 0;
			cachedTime                     =  0;
		}
	}


	public function playAndRepeat(actionName:String):void
	{
		play(actionName, _doRepeat);
	}
	
	
	 /**
	  * 停止
	  * 
	  * @param isPaused
	  */
	public function stop(isPaused:Boolean = false):void
	{
		if (!_playing)  return;
		
		if (!isPaused) 
		{
			_currIndex  =  0;
			cachedTime  =  0;
			_pointer    =  _currGroup[_currIndex];
		}
		
		_playing      =  false;
		m_bufferDirty  =  true;
	}

	
	/* ----------------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★  get × set  ★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------------
	 */


	
	public function get playing():Boolean { return _playing; }

	
	public function get playScale():Number { return _playScale; }
	public function set playScale(value:Number):void
	{
		if(_playScale != value)
		{
			_playScale = value;
			if(_actionOrPointer is String)
			{
				cachedDelay = _section.getActionByName(_actionOrPointer).delay / _playScale;
			}
		}
	}
	
	
	public function get section():String
	{
		return Boolean(_section) ? _section.m_name : null;
	}
	
	
	public function get actionOrPointer():*
	{
		return _actionOrPointer;
	}


	protected function _advancePointer(value:int):void 
	{
		if (_pointer != value)
		{
			_pointer      =  value; 
			m_bufferDirty  =  true;
		}
	}	
	
	
	protected function _doRepeat():void
	{
		if (this._groupLen > 1)
		{
			this._playing = true;
		}

		_pointer      =  _currGroup[_currIndex];
		m_bufferDirty  =  true;
	}
		
	
	override protected function _generateBitmapData():BitmapData 
	{
		return _section.getBitmapByPointer(_pointer);
	}
	

	
	override ns_despair function update(elapsedT:Number):void 
	{
		super.update(elapsedT);
		
		var onComplete:Function;
		
		if (!_playing)  return;
		
		if ((cachedTime += elapsedT) > cachedDelay)
		{
			_currIndex++;
			if (_currIndex >= _groupLen) 
			{	
				_playing    =  false;
				_currIndex  =  0;
				cachedTime     =  0;
				onComplete  =  m_onComplete.animation;
				
				if (onComplete != null)
				{
					onComplete.apply(this, m_onCompleteParams.animation);
				}
				return;
			}
			
			_advancePointer(_currGroup[_currIndex]);
			cachedTime -=  cachedDelay;	
		}
	}
	
	
	
	override ns_despair function destroy():void
	{
		super.destroy();
		
		_section = null;
		_currGroup = null;
		m_onComplete = null;
		m_onCompleteParams = null;
	}
	
}
}